# -*- coding: utf-8 -*-
"""
IP地址输入验证器模块
提供IP地址格式验证功能
"""

import socket
import re
import ipaddress
from PySide2.QtGui import QValidator


class IPValidator(QValidator):
    """IP地址输入验证器"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
    def validate(self, input_str, pos):
        """验证输入的字符串"""
        # 如果为空，允许输入
        if not input_str:
            return QValidator.Intermediate, input_str, pos
            
        # 检查是否包含中文字符
        if re.search(r'[\u4e00-\u9fff]', input_str):
            return QValidator.Invalid, input_str, pos
            
        # 只允许数字和点号
        if not re.match(r'^[0-9.]*$', input_str):
            return QValidator.Invalid, input_str, pos
            
        # 检查点号数量不超过3个
        if input_str.count('.') > 3:
            return QValidator.Invalid, input_str, pos
            
        # 检查是否有连续的点号
        if '..' in input_str:
            return QValidator.Invalid, input_str, pos
            
        # 检查是否以点号开头
        if input_str.startswith('.'):
            return QValidator.Invalid, input_str, pos
            
        # 分割IP段进行验证
        parts = input_str.split('.')
        
        # 检查每个IP段
        for i, part in enumerate(parts):
            if part == '':
                # 如果不是最后一段且为空，则为中间状态
                if i < len(parts) - 1:
                    return QValidator.Invalid, input_str, pos
                continue
                
            # 检查是否为纯数字
            if not part.isdigit():
                return QValidator.Invalid, input_str, pos
                
            # 检查数字范围
            num = int(part)
            if num > 255:
                return QValidator.Invalid, input_str, pos
                
            # 检查前导零（除了单独的0）
            if len(part) > 1 and part.startswith('0'):
                return QValidator.Invalid, input_str, pos
                
        # 如果有4个完整的段，检查是否为完整的IP
        if len(parts) == 4 and all(part.isdigit() and 0 <= int(part) <= 255 for part in parts):
            return QValidator.Acceptable, input_str, pos
            
        # 其他情况为中间状态（正在输入中）
        return QValidator.Intermediate, input_str, pos


class NetworkValidator(QValidator):
    """网段输入验证器"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
    def validate(self, input_str, pos):
        """验证输入的网段字符串"""
        # 如果为空，允许输入
        if not input_str:
            return QValidator.Intermediate, input_str, pos
            
        # 检查是否包含中文字符
        if re.search(r'[\u4e00-\u9fff]', input_str):
            return QValidator.Invalid, input_str, pos
            
        # 检查CIDR格式
        if '/' in input_str:
            return self._validate_cidr_format(input_str, pos)
        else:
            return self._validate_three_segment_format(input_str, pos)
            
    def _validate_cidr_format(self, input_str, pos):
        """验证CIDR格式（如：192.168.1.0/24）"""
        try:
            # 检查基本格式
            if not re.match(r'^[0-9./]*$', input_str):
                return QValidator.Invalid, input_str, pos
                
            # 分割IP和子网掩码
            parts = input_str.split('/')
            if len(parts) > 2:
                return QValidator.Invalid, input_str, pos
                
            ip_part = parts[0]
            mask_part = parts[1] if len(parts) == 2 else ''
            
            # 验证IP部分
            ip_result = self._validate_ip_part(ip_part)
            if ip_result == QValidator.Invalid:
                return QValidator.Invalid, input_str, pos
                
            # 验证子网掩码部分
            if mask_part:
                if not mask_part.isdigit():
                    return QValidator.Invalid, input_str, pos
                mask_num = int(mask_part)
                if mask_num > 32:
                    return QValidator.Invalid, input_str, pos
                    
            # 如果格式完整且正确，尝试验证完整的CIDR
            if len(parts) == 2 and mask_part:
                try:
                    ipaddress.IPv4Network(input_str, strict=False)
                    return QValidator.Acceptable, input_str, pos
                except (ValueError, ipaddress.AddressValueError):
                    return QValidator.Invalid, input_str, pos
                    
            return QValidator.Intermediate, input_str, pos
            
        except Exception:
            return QValidator.Invalid, input_str, pos
            
    def _validate_three_segment_format(self, input_str, pos):
        """验证三段式格式（如：192.168.1）"""
        # 只允许数字和点号
        if not re.match(r'^[0-9.]*$', input_str):
            return QValidator.Invalid, input_str, pos
            
        # 检查点号数量不超过2个（三段式）
        if input_str.count('.') > 2:
            return QValidator.Invalid, input_str, pos
            
        # 检查是否有连续的点号
        if '..' in input_str:
            return QValidator.Invalid, input_str, pos
            
        # 检查是否以点号开头
        if input_str.startswith('.'):
            return QValidator.Invalid, input_str, pos
            
        # 分割网段进行验证
        parts = input_str.split('.')
        
        # 检查每个网段
        for i, part in enumerate(parts):
            if part == '':
                # 如果不是最后一段且为空，则为中间状态
                if i < len(parts) - 1:
                    return QValidator.Invalid, input_str, pos
                continue
                
            # 检查是否为纯数字
            if not part.isdigit():
                return QValidator.Invalid, input_str, pos
                
            # 检查数字范围
            num = int(part)
            if num > 255:
                return QValidator.Invalid, input_str, pos
                
            # 检查前导零（除了单独的0）
            if len(part) > 1 and part.startswith('0'):
                return QValidator.Invalid, input_str, pos
                
        # 如果有3个完整的段，检查是否为完整的网段
        if len(parts) == 3 and all(part.isdigit() and 0 <= int(part) <= 255 for part in parts):
            return QValidator.Acceptable, input_str, pos
            
        # 其他情况为中间状态（正在输入中）
        return QValidator.Intermediate, input_str, pos
        
    def _validate_ip_part(self, ip_str):
        """验证IP部分"""
        if not ip_str:
            return QValidator.Intermediate
            
        # 只允许数字和点号
        if not re.match(r'^[0-9.]*$', ip_str):
            return QValidator.Invalid
            
        # 检查点号数量不超过3个
        if ip_str.count('.') > 3:
            return QValidator.Invalid
            
        # 检查是否有连续的点号
        if '..' in ip_str:
            return QValidator.Invalid
            
        # 检查是否以点号开头
        if ip_str.startswith('.'):
            return QValidator.Invalid
            
        # 分割IP段进行验证
        parts = ip_str.split('.')
        
        # 检查每个IP段
        for i, part in enumerate(parts):
            if part == '':
                if i < len(parts) - 1:
                    return QValidator.Invalid
                continue
                
            if not part.isdigit():
                return QValidator.Invalid
                
            num = int(part)
            if num > 255:
                return QValidator.Invalid
                
            if len(part) > 1 and part.startswith('0'):
                return QValidator.Invalid
                
        # 如果有4个完整的段，检查是否为完整的IP
        if len(parts) == 4 and all(part.isdigit() and 0 <= int(part) <= 255 for part in parts):
            return QValidator.Acceptable
            
        return QValidator.Intermediate


class IPValidationHelper:
    """IP验证辅助类"""
    
    @staticmethod
    def contains_chinese(text):
        """检查文本是否包含中文字符"""
        return bool(re.search(r'[\u4e00-\u9fff]', text))
        
    @staticmethod
    def is_valid_ip(ip_str):
        """验证IP地址格式是否正确"""
        try:
            # 使用socket.inet_aton验证IP格式
            socket.inet_aton(ip_str)
            # 额外检查IP段是否在有效范围内
            parts = ip_str.split('.')
            if len(parts) != 4:
                return False
            for part in parts:
                if not part.isdigit() or not 0 <= int(part) <= 255:
                    return False
            return True
        except socket.error:
            return False
            
    @staticmethod
    def is_valid_network(network_str):
        """验证网段格式是否正确"""
        try:
            # CIDR格式验证
            if '/' in network_str:
                ipaddress.IPv4Network(network_str, strict=False)
                return True
            
            # 三段式格式验证
            if re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}$', network_str):
                parts = network_str.split('.')
                if len(parts) == 3:
                    for part in parts:
                        if not part.isdigit() or not 0 <= int(part) <= 255:
                            return False
                    return True
            
            return False
            
        except (ValueError, ipaddress.AddressValueError):
            return False
            
    @staticmethod
    def clean_chinese_chars(text):
        """移除文本中的中文字符"""
        return re.sub(r'[\u4e00-\u9fff]+', '', text)
        
    @staticmethod
    def extract_ip_from_display_text(display_text):
        """从显示文本中提取IP地址（例如："192.168.1.1 (设备名称)" -> "192.168.1.1"）"""
        if '(' in display_text and ')' in display_text:
            return display_text.split('(')[0].strip()
        return display_text.strip()
        
    @staticmethod
    def normalize_network_format(network_str):
        """标准化网段格式"""
        if not network_str:
            return network_str
            
        # 如果是三段式，转换为CIDR格式
        if re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}$', network_str):
            return f"{network_str}.0/24"
            
        return network_str